# coding=utf-8
import xml.etree.ElementTree as eTree;
import sys;

class DataSetReader:
    """
    为SVM分类器提供数据。数据的格式是XML文件。但是是格式固定
    数据文件格式：
    <DataSet row="3" col="4">
    <Entry id="1"><F1>5.1</F1><F2>3.5</F2><F3>1.4</F3><F4>0.2</F4><C>1</C></Entry>
    <Entry id="2"><F1>4.9</F1><F2>3.0</F2><F3>1.4</F3><F4>0.2</F4><C>-1</C></Entry>
    <Entry id="3"><F1>4.7</F1><F2>3.2</F2><F3>1.3</F3><F4>0.2</F4><C>1</C></Entry>
    </DataSet>
    """
    def __init__(self,strPath):
        """
            初始化XML文件读写器
        """
        try:
            self.__root = eTree.parse(self.__checkPath(strPath)).getroot();
        except IOError, e:
            print "无法打开文件",e;
            sys.exit();
            
    def __checkPath(self,strPath):
        """
            检查文件名是否为字符类型
        """
        if(type(strPath)==type("")):
            return strPath;
        else:
            print "错误的文件名";
            sys.exit();
    def __checkInt(self,num):
        """
            检查输入参数是否为int类型
        """
        if(type(num)==type(0)):
            return num;
        else:
            print "错误的数据类型";
            sys.exit();
        
    def __checkRow(self,row):
        """
            检查输入的参数是否在数据文件样本个数范围内
        """
        if((row<=self.getRow())and(row>0)):
            return row;
        else:
            print "输入的参数超过数据样本个数";
            sys.exit();
    def __checkCol(self,col):
        """
            检查输入的参数是否在样本长度范围内
        """
        if((col<=self.getCol())and(col>0)):
            return col;
        else:
            print "输入的参数超过数据样本的长度范围";
            sys.exit();
        
        
    def getRow(self):
        """
            返回样本的个数
        """
        if(self.__root != None):
            return int(self.__root.attrib['row']);
        else:
            return "错误样本个数"
    
    def getCol(self):
        """
            返回样本的长度
        """
        if(self.__root != None):
            return int(self.__root.attrib['col']);
        else:
            return "错误样本长度";
    
    def getData(self,row,col):
        """
            返回指定位置的样本的值
        """
        row = self.__checkRow(self.__checkInt(row));
        col = self.__checkCol(self.__checkInt(col));

        for entry in self.__root:
            if(int(entry.attrib['id']) == row):
                break;
        for data in entry:
            if(data.tag == 'F'+str(col)):
                break;
        return float(data.text);

    def getClass(self,row):
        """
            返回指定的样本的分类标签
        """
        row = self.__checkRow(self.__checkInt(row));
        for entry in self.__root:
            if(int(entry.attrib['id']) == row):
                break;
        for data in entry:
            if(data.tag == 'C'):
                break;
        return int(data.text);

    def getEntry(self,row):
        """
            返回指定某条样本
        """
        row = self.__checkRow(self.__checkInt(row));
        entry = [];
        for i in range(1,self.getCol()+1):
            entry.append(self.getData(row,i));
        return entry;
